home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-02-19 | 16.8 KB | 449 lines | [TEXT/CWIE] |
-
- #include "AbstractData.h"
-
- //
- // For BlockMoveData
- //
- #include <Memory.h>
-
- //--------------------------------------------------------------------------------
- // CopyMemory
- //
- // The idea of having our own wrapper for memory copying is that memcpy is
- // not always available (it should be, but it doesn't appear in some minimal
- // configurations of CodeWarrior, for example)
- //--------------------------------------------------------------------------------
- void CopyMemory(const void *srcPtr, void *destPtr, SInt32 byteCount)
- {
- BlockMoveData(srcPtr, destPtr, byteCount); // memcpy(destPtr, srcPtr, byteCount);
- }
-
-
- //
- // Global list of compare behaviors
- //
- TAbstractCompareBehavior* TAbstractDataReference::fFirstBehavior = nil;
-
- //================================================================================
- // Class TAbstractCompareBehavior
- //================================================================================
-
- //--------------------------------------------------------------------------------
- // TAbstractCompareBehavior::TAbstractCompareBehavior
- //--------------------------------------------------------------------------------
- TAbstractCompareBehavior::TAbstractCompareBehavior()
- {
- fNextBehavior = nil;
- }
-
- //--------------------------------------------------------------------------------
- // TAbstractCompareBehavior::CompareDynamicBehavior
- //
- // Compare behaviors should look for data types they can compare
- //--------------------------------------------------------------------------------
- CompareEnumeration TAbstractCompareBehavior::CompareDynamicBehavior(const TAbstractDataReference& object1, const TAbstractDataReference& object2) const
- {
- if(fNextBehavior)
- return fNextBehavior->CompareDynamicBehavior(object1, object2);
- else
- return TAbstractDataReference::CompareDefaultBehavior(object1, object2);
- }
-
- //--------------------------------------------------------------------------------
- // TAbstractCompareBehavior::ContainsDynamicBehavior
- //--------------------------------------------------------------------------------
- Boolean TAbstractCompareBehavior::ContainsDynamicBehavior(const TAbstractDataReference& object1, const TAbstractDataReference& object2) const
- {
- if(fNextBehavior)
- return fNextBehavior->ContainsDynamicBehavior(object1, object2);
- else
- return TAbstractDataReference::ContainsDefaultBehavior(object1, object2);
- }
-
- //================================================================================
- // Class TAbstractDataReference
- //================================================================================
-
- //----------------------------------------------------------------------------------------
- // TAbstractDataReference::TAbstractDataReference
- //----------------------------------------------------------------------------------------
- TAbstractDataReference::TAbstractDataReference()
- {
- }
-
- //----------------------------------------------------------------------------------------
- // TAbstractDataReference::~TAbstractDataReference
- //----------------------------------------------------------------------------------------
- TAbstractDataReference::~TAbstractDataReference()
- {
- }
-
- //----------------------------------------------------------------------------------------
- // TAbstractDataReference::DirectlyReadable:
- //----------------------------------------------------------------------------------------
- Boolean TAbstractDataReference::DirectlyReadable() const
- {
- return false;
- } // TAbstractDataReference::DirectlyReadable
-
- //----------------------------------------------------------------------------------------
- // TAbstractDataReference::Writable:
- //----------------------------------------------------------------------------------------
- Boolean TAbstractDataReference::Writable() const
- {
- return false;
- } // TAbstractDataReference::Writable
-
- //----------------------------------------------------------------------------------------
- // TAbstractDataReference::DirectlyWritable:
- //----------------------------------------------------------------------------------------
- Boolean TAbstractDataReference::DirectlyWritable() const
- {
- return false;
- } // TAbstractDataReference::DirectlyWritable
-
- //----------------------------------------------------------------------------------------
- // TAbstractDataReference::Resizable:
- //----------------------------------------------------------------------------------------
- Boolean TAbstractDataReference::Resizable() const
- {
- return false;
- } // TAbstractDataReference::Resizable
-
- //----------------------------------------------------------------------------------------
- // TAbstractDataReference::MaxLength:
- //----------------------------------------------------------------------------------------
- SInt32 TAbstractDataReference::MaxLength() const
- {
- return this->DataLength();
- } // TAbstractDataReference::MaxLength
-
- //----------------------------------------------------------------------------------------
- // TAbstractDataReference::CopyTo:
- //----------------------------------------------------------------------------------------
- SInt32 TAbstractDataReference::CopyTo(char*, SInt32) const
- {
- return 0;
- } // TAbstractDataReference::CopyTo
-
- //----------------------------------------------------------------------------------------
- // TAbstractDataReference::SetDataType:
- //----------------------------------------------------------------------------------------
- Boolean TAbstractDataReference::SetDataType(SInt32)
- {
- return false;
- } // TAbstractDataReference::SetDataType
-
- //----------------------------------------------------------------------------------------
- // TAbstractDataReference::SetDataLength:
- //----------------------------------------------------------------------------------------
- SInt32 TAbstractDataReference::SetDataLength(SInt32)
- {
- return this->DataLength();
- } // TAbstractDataReference::SetDataLength
-
- //----------------------------------------------------------------------------------------
- // TAbstractDataReference::CopyFrom:
- //----------------------------------------------------------------------------------------
- Boolean TAbstractDataReference::CopyFrom(const TAbstractDataReference&, Boolean)
- {
- return false;
- } // TAbstractDataReference::CopyFrom
-
- //----------------------------------------------------------------------------------------
- // TAbstractDataReference::Resize:
- //----------------------------------------------------------------------------------------
- Boolean TAbstractDataReference::Resize(SInt32)
- {
- return false;
- } // TAbstractDataReference::Resize
-
- //----------------------------------------------------------------------------------------
- // TAbstractDataReference::Data:
- //----------------------------------------------------------------------------------------
- const char* TAbstractDataReference::Data() const
- {
- return nil;
- } // TAbstractDataReference::Data
-
- //----------------------------------------------------------------------------------------
- // TAbstractDataReference::Data:
- //----------------------------------------------------------------------------------------
- char* TAbstractDataReference::Data()
- {
- return nil;
- } // TAbstractDataReference::Data
-
- //--------------------------------------------------------------------------------
- // TAbstractDataReference::Compare
- //--------------------------------------------------------------------------------
- CompareEnumeration TAbstractDataReference::Compare(const TAbstractDataReference& object2) const
- {
- //
- // ◊if we're given references that we can't read directly,
- // then we should copy the data somewhere else and compare
- // against that.
- //
- if(this->DirectlyReadable() && object2.DirectlyReadable())
- return TAbstractDataReference::Compare(*this, object2);
- else
- return kCantCompare;
- }
-
- //--------------------------------------------------------------------------------
- // TAbstractDataReference::Contains
- //--------------------------------------------------------------------------------
- Boolean TAbstractDataReference::Contains(const TAbstractDataReference& object2) const
- {
- if((this->DirectlyReadable() == false) || (object2.DirectlyReadable() == false))
- return false;
- else if(fFirstBehavior)
- return fFirstBehavior->ContainsDynamicBehavior(*this, object2);
- else
- return TAbstractDataReference::ContainsDefaultBehavior(*this, object2);
- }
-
- //--------------------------------------------------------------------------------
- // TAbstractDataReference::AddCompareBehavoir
- //--------------------------------------------------------------------------------
- void TAbstractDataReference::AddCompareBehavoir(TAbstractCompareBehavior* behavior)
- {
- if(fFirstBehavior != nil)
- behavior->SetNextBehavior(fFirstBehavior);
-
- fFirstBehavior = behavior;
- } // TAbstractDataReference::AddCompareBehavoir
-
- //--------------------------------------------------------------------------------
- // TAbstractDataReference::Compare
- //--------------------------------------------------------------------------------
- CompareEnumeration TAbstractDataReference::Compare(const TAbstractDataReference& object1, const TAbstractDataReference& object2)
- {
- if(fFirstBehavior)
- return fFirstBehavior->CompareDynamicBehavior(object1, object2);
- else
- return TAbstractDataReference::CompareDefaultBehavior(object1, object2);
- }
-
- //--------------------------------------------------------------------------------
- // TAbstractDataReference::CompareDefaultBehavior
- //
- // If none of the compare behaviors know how to do the data comparison, then
- // assume a simple byte-stream compare is good enough (works for C Strings)
- //--------------------------------------------------------------------------------
- CompareEnumeration TAbstractDataReference::CompareDefaultBehavior(const TAbstractDataReference& object1, const TAbstractDataReference& object2)
- {
- const char* object1Data = object1.Data();
- const char* object2Data = object2.Data();
- SInt32 object1Length = object1.DataLength();
- SInt32 object2Length = object2.DataLength();
- SInt32 bytesToCompare = object1Length > object2Length ? object2Length : object1Length;
-
- //
- // Scan through the first N bytes; stop comparing
- // as soon as an unequal section is found
- //
- while(bytesToCompare)
- {
- if(*object2Data < *object1Data)
- return kSecondObjectComesBefore;
- if(*object2Data > *object1Data)
- return kSecondObjectComesAfter;
-
- ++object1Data;
- ++object2Data;
- --bytesToCompare;
- }
-
- //
- // If the first N bytes of both data streams are
- // the same, then the shorter structure comes before.
- //
- if(object2Length < object1Length)
- return kSecondObjectComesBefore;
- if(object2Length > object1Length)
- return kSecondObjectComesAfter;
-
- //
- // Every byte is equal & the length is the same,
- // so the two objects are equal
- //
- return kObjectKeysEqual;
- }
-
- //--------------------------------------------------------------------------------
- // TAbstractDataReference::ContainsDefaultBehavior
- //--------------------------------------------------------------------------------
- Boolean TAbstractDataReference::ContainsDefaultBehavior(const TAbstractDataReference& object1, const TAbstractDataReference& object2)
- {
- SInt32 sizeDifference = object1.DataLength() - object2.DataLength();
- const char* dataStart = object1.Data();
- Boolean isContained = false;
-
- while(sizeDifference >= 0)
- {
- TConstDataReference containsTest(object1.DataType(), dataStart, object2.DataLength());
- if(containsTest.Compare(object2) == kObjectKeysEqual)
- {
- isContained = true;
- break;
- }
- ++dataStart;
- --sizeDifference;
- }
-
- return isContained;
- } // TAbstractDataReference::ContainsDefaultBehavior
-
- //================================================================================
- // Class TConstDataReference
- //================================================================================
-
- //----------------------------------------------------------------------------------------
- // TConstDataReference::DirectlyReadable:
- //----------------------------------------------------------------------------------------
- Boolean TConstDataReference::DirectlyReadable() const
- {
- return true;
- } // TConstDataReference::DirectlyReadable
-
- //----------------------------------------------------------------------------------------
- // TConstDataReference::DataType:
- //----------------------------------------------------------------------------------------
- SInt32 TConstDataReference::DataType() const
- {
- return fDataType;
- } // TConstDataReference::DataType
-
- //----------------------------------------------------------------------------------------
- // TConstDataReference::DataLength:
- //----------------------------------------------------------------------------------------
- SInt32 TConstDataReference::DataLength() const
- {
- return fDataLength;
- } // TConstDataReference::DataLength
-
- //----------------------------------------------------------------------------------------
- // TConstDataReference::CopyTo:
- //----------------------------------------------------------------------------------------
- SInt32 TConstDataReference::CopyTo(char* destination, SInt32 maxBytesToCopy) const
- {
- SInt32 bytesToCopy = (fDataLength > maxBytesToCopy) ? maxBytesToCopy : fDataLength;
-
- CopyMemory(fData, destination, bytesToCopy);
-
- return bytesToCopy;
- } // TConstDataReference::CopyTo
-
- //----------------------------------------------------------------------------------------
- // TConstDataReference::Data:
- //----------------------------------------------------------------------------------------
- const char* TConstDataReference::Data() const
- {
- return fData;
- } // TConstDataReference::Data
-
- //================================================================================
- // Class TUpdataDataReference
- //================================================================================
-
- //--------------------------------------------------------------------------------
- // TUpdataDataReference::Writable
- //--------------------------------------------------------------------------------
- Boolean TUpdataDataReference::Writable() const
- {
- return true;
- }
-
- //--------------------------------------------------------------------------------
- // TUpdataDataReference::DirectlyWritable
- //--------------------------------------------------------------------------------
- Boolean TUpdataDataReference::DirectlyWritable() const
- {
- return true;
- }
-
- //--------------------------------------------------------------------------------
- // TUpdataDataReference::MaxLength
- //--------------------------------------------------------------------------------
- SInt32 TUpdataDataReference::MaxLength() const
- {
- return fMaxLength;
- }
-
- //--------------------------------------------------------------------------------
- // TUpdataDataReference::SetDataType
- //--------------------------------------------------------------------------------
- Boolean TUpdataDataReference::SetDataType(SInt32 newType)
- {
- fDataType = newType;
- return true;
- }
-
- //--------------------------------------------------------------------------------
- // TUpdataDataReference::SetDataLength
- //--------------------------------------------------------------------------------
- SInt32 TUpdataDataReference::SetDataLength(SInt32 newLength)
- {
- fDataLength = newLength > fMaxLength ? fMaxLength : newLength;
-
- return fDataLength;
- }
-
- //--------------------------------------------------------------------------------
- // TUpdataDataReference::CopyFrom
- //--------------------------------------------------------------------------------
- Boolean TUpdataDataReference::CopyFrom(const TAbstractDataReference& source, Boolean allowDataToClip)
- {
- Boolean copyFits = source.DataLength() <= fMaxLength;
-
- if(copyFits || allowDataToClip)
- {
- fDataLength = source.CopyTo(this->Data(), fMaxLength);
- this->SetDataType(source.DataType());
- }
-
- return copyFits;
- } // TUpdataDataReference::CopyFrom
-
- //--------------------------------------------------------------------------------
- // TUpdataDataReference::Data
- //--------------------------------------------------------------------------------
- char* TUpdataDataReference::Data()
- {
- return (char*)fData;
- }
-
- //================================================================================
- // Class TTransientDataReference
- //================================================================================
-
- //--------------------------------------------------------------------------------
- // TTransientDataReference::TTransientDataReference
- //--------------------------------------------------------------------------------
- TTransientDataReference::TTransientDataReference(const TAbstractDataReference& data) :
- TConstDataReference(data.DataType(), nil, data.DataLength()), fAllocatedData(false)
- {
- if(data.DirectlyReadable() == false)
- {
- fData = new char[data.DataLength()];
- fAllocatedData = true;
-
- data.CopyTo((char*)fData, fDataLength);
- }
- else
- {
- fData = data.Data();
- }
- }
-
- //--------------------------------------------------------------------------------
- // TTransientDataReference::~TTransientDataReference
- //--------------------------------------------------------------------------------
- TTransientDataReference::~TTransientDataReference()
- {
- if(fAllocatedData)
- delete (char*)fData;
- }
-
-